
/* A simple server in the internet domain using TCP
   The port number is passed as an argument 
   This version runs forever, forking off a separate 
   process for each connection
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string.h>
#include <signal.h>
#include <sched.h>
#include <sys/shm.h>
#include <crafter.h>
 
using namespace std;
using namespace Crafter;


typedef struct params
{
    char nombre[1];
    int socket;
};


int dostuff(void *);
int injection(void *);
void error(const char *msg)
{
    std::cout<<"error"<<std::endl;
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     
     params args;
     void *stack=malloc(65536);
     int sockfd, newsockfd, portno, optval;
     socklen_t clilen;
     struct sockaddr_in serv_addr, cli_addr;
     socklen_t optlen = sizeof(optval);
     int n;
     
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     std::cout<<"Este es el socket de atadura: "<<sockfd<<std::endl;
     optval = 1;
     optlen = sizeof(optval);
     
     if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) 
         perror("setsockopt()");
     
     if(sockfd < 0) 
        error("ERROR opening socket");
    
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
   
     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
         error("ERROR on binding");
     
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     
     


       
         while (true) 
         {
             newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
         
             if (newsockfd < 0)     
                 error("ERROR on accept");
           
             
             args.socket=newsockfd;
             bzero((char *) &args.nombre, sizeof(args.nombre));
             n = read(newsockfd,args.nombre,1);
             
             if(n < 0)
                 error("ERROR reading the socket");
             
             
             else
             {
                void* arg =(void*)&args;
                clone(dostuff, stack+65536,0, arg);
                //clone(injection, stack+65536,0, arg); 
                 
             }
             
         }  /* end of while */
     close(sockfd);
     return 0; /* we never get here */
}

/******** DOSTUFF() *********************
 There is a separate instance of this function 
 for each connection.  It handles all communication
 once a connnection has been established.
 *****************************************/
int dostuff (void *args)
{
    params *arg;
    int  n,nmsg,socket,tiempo;
    char buffer[255];
    char cont[10],tie[1];
    char nombre[64];
    char line[128];
    char archivo='s';
    char id[]="Este es tu mensaje #:";
    static const char filename[] = "Himno.txt";
    FILE *file = fopen ( filename, "r" );
    
    arg=(params*)malloc(sizeof(params));  
    arg=(params*)args;
    socket=arg->socket;
    tie[0]=arg->nombre[0];
    tiempo=atoi(tie);
    std::cout<< tiempo<< endl;
    //strcpy(nombre,arg->nombre);
    nmsg=0;
    std::cout<<"El cliente: "<<nombre<<"ha generado el socket: "<<socket<<std::endl;
    
    while(fgets ( line, sizeof line, file ) !=NULL )
    { 
       nmsg++;
       bzero((char *) &buffer, sizeof(buffer));
       bzero((char *) &cont, sizeof(cont));
       sprintf(cont,"%d",nmsg);
       strcat(buffer,"\nHola: ");
       strcat(buffer,nombre);
       strcat(buffer,id);
       strcat(buffer,cont);
       strcat(buffer,"\n");
       n = write(socket,line,sizeof(line));
      bzero((char *) &line, sizeof(line));
       if (n < 0) 
           std::cout<<"error en write"<<std::endl;
        
       sleep (tiempo);
       
   }
}

